home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
-
- Keeper -- written by Ray Lambert for Theta Systems, Inc.
-
- Copyright 1991 Commodore Business Machines, Inc.
-
- Purpose and Usage:
-
- Keeper is meant for use in a startup-sequence file to display a
- picture while booting. Some applications are quite large and take a
- significant period of time to load. Unless special steps are taken,
- an application such as this cannot display anything for the user to look
- at until the executable file is completely loaded. This keeps the user
- waiting and the inactivity makes the load time seem even longer. This
- practice is not acceptable for a platform such as CDTV were the task of
- keeping the user's attention and preventing the user from becoming bored
- is considered paramount. Keeper was written to provide a solution to
- this problem. Keeper should be invoked from your startup-sequence file
- (in the foreground: do not use RUN) with the name of an IFF.ILBM picture
- to be displayed. Keeper loads the picture and then spawns off a tiny
- task which displays the picture and frees all the resources that are used
- to do so when it is time to remove the picture. Keeper quits shortly
- after these things are done allowing the remainder of the startup-sequence
- to be executed. Because keeper runs in the foreground while it is loading
- the picture, there will not be a problem with two processes trying to read
- from the same disk at once (this would slow the boot process considerably).
- Note that this can still occur however if a program gets run in the
- background before keeper is run, and that program reads from the disk
- (this should be avoided). There are three ways to make keeper remove its
- picture. First, if keeper is run a second time with the keyword 'QUIT' on
- its command line, keeper will cause a previous copy of itself to terminate.
- Second (and easier), the simple act of loading another View will cause
- keeper to terminate. Keeper accomplishes this by periodically checking
- the GfxBase->ActiView variable to see if its View has been replaced. Note
- that because of this it is dangerous for a program to save the active
- View during initialization and then try to restore it later. Please use
- CloseWorkBench() and OpenWorkBench() instead if possible. A third method
- of terminating keeper is by Signal()'ing it directly. Keeper's task can
- be located like this:
-
- task = FindTask("PicKeeper");
-
- and terminated like this:
-
- Signal(task,SIGBREAKF_CTRL_C);
-
- Keeper can display any IFF picture including overscan. Keeper
- automatically compensates for PAL by centering its View appropriately.
- Keeper CANNOT display pictures that require custom copper list code such
- as Dynamic HAM pics. Keeper reads the CDTV preferences and uses the saved
- screen centering information found there. If the preferences have not
- been set or are not available (not running on a baby) the centering data
- gets stolen from Intuition's View (actually it is the active View at the
- time keeper runs).
-
- ****************************************************************************/
-
- #include <stdio.h>
- #include "keeper.h"
- #include <exec/memory.h>
- #include <graphics/gfxbase.h>
- #include <graphics/view.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/dos.h>
- #include "cdtvprefs.h"
-
- extern int keeper(struct View *, struct MemList *);
-
- struct GfxBase *GfxBase=0;
- struct Library *IntuitionBase=0;
- struct View *v=0;
- struct ViewPort *vp=0;
- struct RasInfo *ri=0;
- struct BitMap *bm=0;
- struct ColorMap *cm=0;
- struct BLITmap *pic=0;
- struct MemList *ml=0;
- BOOL vpmade = FALSE;
- struct CDTVPrefs prefs;
-
-
- ULONG mlsize;
-
- struct MemList *BuildMemList(void)
- {
- register struct MemList *ml;
- register struct MemEntry *me;
- register UWORD cnt;
- ULONG size;
-
- cnt = ((pic->d + 4) - 1);
- mlsize = (sizeof(struct MemList) + (cnt * sizeof(struct MemEntry)));
- unless( ml = (struct MemList *)AllocMem(mlsize,MEMF_PUBLIC|MEMF_CLEAR) )
- return(0);
- ml->ml_NumEntries = (cnt + 1);
- me = &ml->ml_ME[0];
- /** include all of the blitplanes **/
- size = RASSIZE(pic->w,pic->h);
- for(cnt = 0; cnt < pic->d; cnt++)
- {
- me->me_Addr = (APTR)pic->p[cnt];
- me->me_Length = size;
- me++;
- }
- /** include the View struct **/
- me->me_Addr = (APTR)v;
- me->me_Length = sizeof(struct View);
- me++;
- /** include the ViewPort struct **/
- me->me_Addr = (APTR)vp;
- me->me_Length = sizeof(struct ViewPort);
- me++;
- /** include the RasInfo struct **/
- me->me_Addr = (APTR)ri;
- me->me_Length = sizeof(struct RasInfo);
- me++;
- /** include the BitMap struct **/
- me->me_Addr = (APTR)bm;
- me->me_Length = sizeof(struct BitMap);
-
- return(ml);
- }
-
-
- void say(char *msg)
- {
- static BPTR console;
- unless( console ) unless( console = Output() ) return;
- Write(console,msg,strlen(msg));
- }
-
-
- void xit(char *msg, int rc)
- {
- if (ml) FreeMem(ml,mlsize);
- if (pic) unloadILBM(pic);
- if (cm) FreeColorMap(cm);
- if (bm) FreeMem(bm,sizeof(struct BitMap));
- if (ri) FreeMem(ri,sizeof(struct RasInfo));
- if (vpmade)
- {
- if (v->LOFCprList) FreeCprList(v->LOFCprList);
- if (v->SHFCprList) FreeCprList(v->SHFCprList);
- FreeVPortCopLists(vp);
- }
- if (vp) FreeMem(vp,sizeof(struct ViewPort));
- if (v) FreeMem(v,sizeof(struct View));
- if (GfxBase) CloseLibrary(GfxBase);
- if (IntuitionBase) CloseLibrary(IntuitionBase);
- if (msg) say(msg);
- exit(rc);
- }
-
-
- #if DBG
- struct BitDefs
- {
- ULONG bd_bit;
- ULONG bd_mask;
- char *bd_text;
- }
- mode_bits[] =
- {
- { (ULONG)HIRES, (ULONG)HIRES, "HIRES" },
- { (ULONG)LACE, (ULONG)LACE, "LACE" },
- { (ULONG)HAM, (ULONG)HAM, "HAM" },
- { (ULONG)EXTRA_HALFBRITE, (ULONG)EXTRA_HALFBRITE, "EXTRA_HALFBRITE" },
- { (ULONG)SPRITES, (ULONG)SPRITES, "SPRITES" },
- { (ULONG)DUALPF, (ULONG)DUALPF, "DUALPF" },
- { (ULONG)PFBA, (ULONG)PFBA, "PFBA" },
- { (ULONG)VP_HIDE, (ULONG)VP_HIDE, "VP_HIDE" },
- { (ULONG)GENLOCK_AUDIO, (ULONG)GENLOCK_AUDIO, "GENLOCK_AUDIO" },
- { (ULONG)GENLOCK_VIDEO, (ULONG)GENLOCK_VIDEO, "GENLOCK_VIDEO" },
- { 0, 0, 0, }
- };
-
- char *ShowBitDefs(char *buffer, ULONG fbits, struct BitDefs *bd)
- {
- register char *buf, *p;
- BOOL flag = FALSE; /* flag to output a "|" or not */
- if (fbits == NULL)
- {
- strcpy(buffer,"NULL");
- return(buffer);
- }
- buf = buffer;
- while(bd->bd_text != NULL)
- {
- if ((fbits & bd->bd_mask) == bd->bd_bit)
- {
- if (flag)
- *buf++ = '|';
- else
- flag = TRUE;
- for(p = bd->bd_text; *p; p++, buf++) *buf = *p;
- }
- bd++;
- }
- if (!flag)
- {
- sprintf(buffer,"0x%08X",fbits);
- return(buffer);
- }
- *buf = 0;
- return(buffer);
- }
-
-
- void showpicinfo(void)
- {
- char s[200];
- sprintf(s,"Picture: %hd X %hd X %hd, ",pic->w,pic->h,pic->d);
- say(s);
- ShowBitDefs(s,(pic->modes&(HIRES|LACE|HAM|EXTRA_HALFBRITE)),mode_bits);
- say(s);
- sprintf(s,"\nViewPort: %hd,%hd,%hd,%hd\n",v->DxOffset,v->DyOffset,vp->DWidth,vp->DHeight);
- say(s);
- }
- #endif
-
-
- main(int argc, char *argv[])
- {
- short normal, picture, maximum, i;
-
- unless( argc == 2 ) xit("Usage: keeper <picname | QUIT>\n",5);
- if (stricmp(argv[1],"QUIT") == 0)
- {
- register struct Task *t;
- if ( t = FindTask("PicKeeper") ) Signal(t,SIGBREAKF_CTRL_C);
- xit(0,0);
- }
- unless( IntuitionBase = OpenLibrary("intuition.library",0) ) xit(0,255);
- unless( GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0) )
- xit(0,255);
- unless( v = (struct View *)AllocMem(sizeof(struct View),MEMF_PUBLIC|MEMF_CLEAR) )
- xit("No memory for View\n",21);
- unless( vp = (struct ViewPort *)AllocMem(sizeof(struct ViewPort),MEMF_PUBLIC|MEMF_CLEAR) )
- xit("No memory for ViewPort\n",21);
- unless( ri = (struct RasInfo *)AllocMem(sizeof(struct RasInfo),MEMF_PUBLIC|MEMF_CLEAR) )
- xit("No memory for RasInfo\n",21);
- unless( bm = (struct BitMap *)AllocMem(sizeof(struct BitMap),MEMF_PUBLIC|MEMF_CLEAR) )
- xit("No memory for BitMap\n",21);
- unless( cm = GetColorMap(32) ) xit("No memory for ColorMap\n",21);
- unless( pic = loadILBM(argv[1]) ) xit("Unable to load picture\n",21);
- InitView(v);
- InitVPort(vp);
- v->ViewPort = vp;
- vp->RasInfo = ri;
- ri->BitMap = bm;
- BLITmap2BitMap(pic,bm);
-
- vp->ColorMap = cm;
- LoadRGB4(vp,pic->cmap,(1 << pic->d));
-
- maximum = 368;
- if (pic->modes & HIRES) maximum *= 2;
- vp->DWidth = min(pic->w,maximum);
-
- maximum = (GfxBase->DisplayFlags & PAL) ? 283 : 241;
- if (pic->modes & LACE) maximum *= 2;
- vp->DHeight = min(pic->h,maximum);
-
- vp->Modes = (pic->modes & (HIRES|LACE|HAM|EXTRA_HALFBRITE));
- v->Modes = (pic->modes & LACE);
-
- ReadPrefs(&prefs);
-
- normal = GfxBase->NormalDisplayColumns;
- if (normal >= 640) normal /= 2; /* adjust to LORES pixels */
- picture = vp->DWidth;
- if (vp->Modes & HIRES) picture /= 2; /* ditto */
- if (picture <= normal)
- v->DxOffset = (prefs.DisplayX + ( (normal - picture) / 2));
- else
- v->DxOffset = (prefs.DisplayX - ( (picture - normal) / 2));
- /* correct X offset to prevent edge jitters (must be on 8 bit boundary) */
- i = (v->DxOffset % 8);
- if (i > 4)
- {
- v->DxOffset += (8 - i);
- }
- else
- {
- v->DxOffset -= i;
- }
-
- normal = GfxBase->NormalDisplayRows;
- if (normal >= 400) normal /= 2; /* adjust to LORES pixels */
- picture = vp->DHeight;
- if (vp->Modes & LACE) picture /= 2; /* ditto */
- if (picture <= normal)
- v->DyOffset = (prefs.DisplayY + ( (normal - picture) / 2));
- else
- v->DyOffset = (prefs.DisplayY - ( (picture - normal) / 2));
-
- MakeVPort(v,vp);
- MrgCop(v);
- vpmade = TRUE;
-
- #if DBG
- showpicinfo();
- #endif
-
- unless( ml = BuildMemList() ) xit("Couldn't create MemList\n",10);
- unless( keeper(v,ml) ) xit("Couldn't create task\n",10);
-
- /* keeper will close all of these... */
- vpmade = FALSE;
- v = 0;
- vp = 0;
- ri = 0;
- bm = 0;
- cm = 0;
- pic->d = 0; /* keeper keeps the bit planes */
- ml = 0;
- GfxBase = 0;
- IntuitionBase = 0;
- xit(0,0);
- }
-